import {defineStore} from "pinia";
import {watch} from "vue";
import {CanvasSource, Map as MapboxMap} from 'mapbox-gl';
import WindFeatherLayer from 'common/src/utils/mapboxCustom/WindFeather';
import ColorMap from 'common/src/utils/mapboxCustom/ColorMap';
import WaveDirection from 'common/src/utils/mapboxCustom/WaveDirection';
import Particle from 'common/src/utils/mapboxCustom/Particle';
import {
    grayLandLayerId, hideIsobarLayer, hideLayersFromLayerIds, initIsobarLayer,
    showIsobarLayer, showLayersFromLayerIds, updateIsobarConfig,
    waveDirLayer, weathervColormapLayerId, windCanvasLayer, weathervParticleLayerId,
    climateColormapLayerId,
} from "common/src/utils/layer";
import {MapboxClient} from 'weatherv';
import {
    getLocalWeatherUrl,
    initTargetList,
    WeatherToolType,
    WeatherType
} from "common/src/utils/weather";
import {useTimeRangeStore, useTaskStore} from "@/store";
import {isLinkAvailable} from "common/src/utils/func";
import {ColorRampData} from "common/src/utils/color";
import {getPressureLine} from "@/services/data";

/** 数据源类型 */
export enum DataSource {
    /** 中国气象局 */
    cma = 'cma',
    /** 欧洲气象中心 */
    ec = 'ec',
    /** 海二代 */
    plan = 'plan',
}

interface WeatherState {
    /** 当前mapbox实例 */
    map: MapboxMap | null;
    /** 当前mapbox容器 */
    mapDiv: HTMLDivElement | null;
    /** 地图模式：'2d' | 'globe' */
    mapMode: '2d' | 'globe';
    /** 当前weatherv实例 */
    client: MapboxClient;
    /** 当前显示的气象要素 */
    activeWeather: string | undefined;
    /** 粒子动画是否打开 */
    particleActive: boolean;
    /** 等压线是否打开 */
    isoActive: boolean;
    /** 风羽图是否打开 */
    featherActive: boolean;
    /** 浪方向是否打开 */
    waveDirActive: boolean;
    /** 气候区划图层是否打开 */
    climateLayerActive: boolean;
    /** 是否处于任务筹划阶段 */
    isTaskPhaseOne: boolean;
    /** 风图层-风羽 */
    windFeather?: WindFeatherLayer;
    /** 色斑图图层 */
    weatherLayer?: ColorMap;
    /** 气候区划图层 */
    climateLayer?: ColorMap;
    /** 浪方向图层 */
    waveDirection?: WaveDirection;
    /** 粒子动画图层 */
    particle?: Particle;
    /** 数据源 */
    dataSource?: string;
    /** 是否已注册 dataSource 变更 watcher（避免重复） */
    dataSourceWatcherInited?: boolean;
}

export const useWeatherStore = defineStore('weather', {
    state: (): WeatherState => ({
        map: null,
        mapDiv: null,
        mapMode: '2d',
        client: new MapboxClient(),
        activeWeather: undefined,
        particleActive: false,
        isoActive: false,
        featherActive: false,
        waveDirActive: false,
        climateLayerActive: false,
        isTaskPhaseOne: false,
        dataSource: 'ec',
        dataSourceWatcherInited: false,
    }),
    actions: {
        async initWeatherLayer(map: MapboxMap, needInitLayer = true) {
            // @ts-ignore
            this.map = map;
            const mapDiv = document.getElementById('map') as HTMLDivElement;
            this.mapDiv = mapDiv;
            this.weatherLayer = new ColorMap(weathervColormapLayerId);
            map.addLayer(this.weatherLayer as any, grayLandLayerId);
            this.climateLayer = new ColorMap(climateColormapLayerId);
            map.addLayer(this.climateLayer as any, grayLandLayerId);
            this.particle = new Particle(weathervParticleLayerId);
            map.addLayer(this.particle);
            // // 初始化 粒子动画 图层实例
            // this.client.initParticleLayer(map, mapDiv, { layerId: weathervParticleLayerId, beforeId: grayLandLayerId });
            // const particleSourceId = map.getLayer(weathervParticleLayerId)?.source as string;
            // console.log(particleSourceId, map.getSource(particleSourceId!), map.getStyle());
            // // map.setConfig()
            // (map.getSource(particleSourceId!) as CanvasSource).animate = false;
            this.waveDirection = new WaveDirection(waveDirLayer);
            map.addLayer(this.waveDirection);
            this.windFeather = new WindFeatherLayer();
            map.addLayer(this.windFeather);
            // 初始化气压线图层
            initIsobarLayer(map, windCanvasLayer);
            // 监听数据源切换：当已有 activeWeather 展示时，切换数据源需重新计算并加载对应 URL
            if (!this.dataSourceWatcherInited) {
                watch(
                    () => this.dataSource,
                    () => {
                        if (this.activeWeather) {
                            this.setActiveWeather(this.activeWeather);
                        }
                    }
                );
                this.dataSourceWatcherInited = true;
            }
        },
        async setActiveWeather(weather?: string, srcOptions: string[] = []) {
            if (!weather || !this.activeWeather) {
                // 气象图层显示与否影响气压线颜色
                // @ts-ignore
                updateIsobarConfig(this.map!, !!weather);
                // 风羽颜色
                this.windFeather?.setFeatherColor(
                    weather ? [1.0, 1.0, 1.0, 1.0] : [0.2, 0.2, 0.2, 1.0]
                );
            }
            this.activeWeather = weather;
            if (weather) {
                const timeRange = useTimeRangeStore();
                let url = ''
                // if (this.dataSource === DataSource.ec) {
                //     url = `${import.meta.env.BASE_URL}test/${this.dataSource}_${weather}.png`;
                // } else if (this.dataSource === DataSource.cma) {
                //     url = `${import.meta.env.BASE_URL}test/${this.dataSource}_${weather}.png`;
                // } else if (this.dataSource === DataSource.plan) {
                //     url = getWeatherUrl(weather, timeRange.currentTime);
                // }
                url = getLocalWeatherUrl(weather, timeRange.currentTime, <string>this.dataSource)

                const taskStore = useTaskStore();
                url = taskStore.replaceUrlDir(url)
                console.log('图片路径====>', url);

                const factor = initTargetList[weather].factor;
                this.weatherLayer?.setConfig(factor, url);
                this.weatherLayer?.toggleDisplay(true);
                // @ts-ignore
                showLayersFromLayerIds(this.map, [grayLandLayerId]);
            } else {
                this.hideColorLayer();
            }
        },
        updateWeatherLayer(time: number) {
            if (!this.map || !this.activeWeather) {
                return;
            }
            let url = getLocalWeatherUrl(this.activeWeather, time);
            const taskStore = useTaskStore();
            url = taskStore.replaceUrlDir(url)
            const factor = initTargetList[this.activeWeather].factor;
            this.weatherLayer?.setConfig(factor, url);
        },
        hideColorLayer() {
            this.dataSource = 'ec'
            this.weatherLayer?.toggleDisplay(false);
            // @ts-ignore
            hideLayersFromLayerIds(this.map, [grayLandLayerId]);
        },
        updateClimateLayer(url: string, color?: ColorRampData, step?: boolean) {
            this.climateLayer?.setConfig(undefined, url, color, step);
            this.climateLayer?.toggleDisplay(true);
            this.climateLayerActive = true;
            this.setActiveWeather();
            this.hideFeatherLayer();
            this.hideIsobar();
            this.hideParticleLayer();
            this.hideWaveDirLayer();
            // @ts-ignore
            showLayersFromLayerIds(this.map, [grayLandLayerId]);
        },
        hideClimateLayer() {
            this.climateLayer?.toggleDisplay(false);
            this.climateLayerActive = false;
            // @ts-ignore
            hideLayersFromLayerIds(this.map, [grayLandLayerId]);
        },
        async updateIsobar(interval = 5) {
            this.isoActive = true;
            const timeRange = useTimeRangeStore();
            // if (!this.baseIsobarUrl) {
            //   this.baseIsobarUrl = await getOriginalUrl('isobar');
            // }
            // const url = getRasterUrl(this.baseIsobarUrl, timeRange.currentTime, this.pressureSrc, 'pressure');
            let url = getLocalWeatherUrl(WeatherToolType.pressureLine, timeRange.currentTime);
            const taskStore = useTaskStore();
            url = taskStore.replaceUrlDir(url)
            if (url === '/draw/process/isonline') {
                const jsonText = await getPressureLine({file_path: '', interval});
                const text = JSON.parse(jsonText);
                showIsobarLayer(this.map!, text);
                return;
            }
            const exist = await isLinkAvailable(url);
            if (exist) {
                // @ts-ignore
                showIsobarLayer(this.map!, url);
            } else {
                // @ts-ignore
                hideIsobarLayer(this.map!);
            }
        },
        hideIsobar() {
            this.isoActive = false;
            if (this.map) {
                // @ts-ignore
                hideIsobarLayer(this.map);
            }
        },
        /** 更新风羽图 */
        async updateFeatherLayer() {
            if (!this.map) {
                return;
            }
            this.featherActive = true;
            const timeRange = useTimeRangeStore();
            // if (!this.baseFeatherUrl) {
            //   this.baseFeatherUrl = await getOriginalUrl(WeatherType.wind);
            // }
            // const url = getRasterUrl(this.baseFeatherUrl, timeRange.currentTime, this.windSrc, WeatherType.wind);
            let url = getLocalWeatherUrl(WeatherType.wind, timeRange.currentTime);
            const taskStore = useTaskStore();
            url = taskStore.replaceUrlDir(url)
            this.windFeather?.loadImageAndCreateTextureInfo(url);
            this.windFeather?.toggleDisplay(true);
        },
        hideFeatherLayer() {
            if (this.map) {
                this.featherActive = false;
                this.windFeather?.toggleDisplay(false);
            }
        },
        async updateParticleLayer() {
            if (!this.map) {
                return;
            }
            this.particleActive = true;
            const timeRange = useTimeRangeStore();
            const weather = WeatherType.wind;
            let url = getLocalWeatherUrl(weather, timeRange.currentTime);
            const taskStore = useTaskStore();
            url = taskStore.replaceUrlDir(url)
            const factor = initTargetList[weather].factor;
            this.particle?.setConfig({factor, url, particlesNumber: 10000});
            this.particle?.toggleDisplay(true);
        },
        hideParticleLayer() {
            if (!this.map) {
                return;
            }
            this.particle?.toggleDisplay(false);
            this.particleActive = false;
        },
        async updateWaveDirLayer() {
            if (!this.map) {
                return;
            }
            this.waveDirActive = true;
            const timeRange = useTimeRangeStore();
            let url = getLocalWeatherUrl(WeatherType.seawave, timeRange.currentTime);
            const taskStore = useTaskStore();
            url = taskStore.replaceUrlDir(url)
            this.waveDirection?.loadImageAndCreateTextureInfo(url);
            this.waveDirection?.toggleDisplay(true);
        },
        hideWaveDirLayer() {
            if (!this.map) {
                return;
            }
            this.waveDirActive = false;
            this.waveDirection?.toggleDisplay(false);
        },
    },

});
